package database

import (
	"errors"
	"fmt"
	models "huijing_mall/internal/database/models"
	"huijing_mall/shared/common"
	"huijing_mall/shared/kernel/hmErrors"
	"huijing_mall/variable"
	"strings"
	"time"

	"github.com/bytedance/sonic"
	"gorm.io/gorm"

	loggers "huijing_mall/pkg/logger"
)

func FindAll(db *gorm.DB) (boosdata []models.SelectBoss, err error) {
	res := db.Find(&boosdata)
	if res.Error != nil {
		fmt.Println(res.Error)
		err = errors.New("获取数据错误")
		return nil, err
	}
	return boosdata, nil
}

func Del(db *gorm.DB, name string) bool {
	res := db.Where("job_name= ?", name).Delete(&models.Boss{})
	if res.Error != nil {
		fmt.Println(res.Error)
		return false
	}
	return true
}

func FindAreaData(db *gorm.DB, address string) (boosdata []models.SelectBoss, err error) {
	res := db.Where("city_name=? AND deleted_at IS NULL", address).Find(&boosdata)
	if res.Error != nil {
		loggers.Info(res.Error.Error())
		return nil, errors.New("获取数据错误")
	}

	return boosdata, nil
}

func Insert(db *gorm.DB, cityName, cityCode string) error {
	ad := models.Area{
		CityName: cityName,
		CityCode: cityCode,
	}
	res := db.Create(&ad)
	if res.Error != nil {
		fmt.Println(res.Error)
		return errors.New("添加错误")
	}
	return nil
}

func FindOneAreaCode(db *gorm.DB, cityName string) (area models.Area, err error) {
	res := db.Where("city_name=? AND deleted_at IS NULL", cityName).First(&area)
	if res.Error != nil {
		fmt.Println(res.Error)
		return area, errors.New("查询错误或该系统内不存在此地区")
	}
	if area.CityCode == "" {
		return area, errors.New("未找到该地区活不存在")
	}
	return area, err
}

func Query(db *gorm.DB, key string) (tk models.Task, err error) {
	res := db.Where("task_key =?", key).Find(&tk)
	if res.Error != nil {
		fmt.Println(res.Error)
		return tk, errors.New("获取数据错误")
	}
	return tk, nil
}

func CreatTk(db *gorm.DB, task *models.Task) error {
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Create(task).Error
	})
	if res != nil {
		fmt.Println(res.Error())
		return errors.New("任务创建失败")
	}
	return nil
}

func UpdateTk(db *gorm.DB, taskKey, status string, data interface{}) error {
	marshal, _ := sonic.Marshal(data)
	//db.Begin()
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Where("task_key= ? ", taskKey).Updates(models.Task{TaskStatus: status, TaskData: marshal}).Error
	})
	if res != nil {
		//db.Rollback()
		fmt.Println(res.Error())
		return errors.New("任务更新失败")
	}
	//db.Commit()
	return nil
}

func UpdateUserPhoto(db *gorm.DB, uid uint, imgSrc string) error {
	//db.Begin()
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Table("user").Where("ID= ? ", uid).Update("avatar", imgSrc).Error
	})
	if res != nil {
		//db.Rollback()
		return errors.New("头像更新失败")
	}
	//db.Commit()
	return nil
}

func SaveHistory(db *gorm.DB, photoHistory models.UserAvatarHistory) error {
	//db.Begin()
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Model(&models.UserAvatarHistory{}).Save(&photoHistory).Error
	})
	if res != nil {
		//db.Rollback()
		return errors.New("头像更新失败")
	}
	//db.Commit()
	return nil
}

func GetHistory(db *gorm.DB, uid uint) (history []models.UserAvatarHistory, err error) {
	res := db.Where("ID = ? and is_current = 1", uid).Find(&history)
	if res.Error != nil {
		loggers.Error(fmt.Sprintf("获取历史记录失败: %v", res.Error))
		return nil, fmt.Errorf("获取历史记录失败")
	}
	return history, nil
}

func UpdateHistory(db *gorm.DB, uid uint) error {
	//db.Begin()
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Model(&models.UserAvatarHistory{}).Where("ID= ?", uid).Update("is_current", "0").Error
	})
	if res != nil {
		//db.Rollback()
		return errors.New("头像更新失败")
	}
	//db.Commit()
	return nil
}

func QueryTk(db *gorm.DB, taskKey string) (task models.TaskKey, err error) {
	res := db.Where("task_key=?", taskKey).Find(&task)
	if res.Error != nil {
		fmt.Println(res.Error)
		return models.TaskKey{}, errors.New("获取任务key失败")
	}
	return task, nil
}

func UpdatePwd(db *gorm.DB, username, mobile, pwd string) error {
	//db.Begin()
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		if strings.Contains(mobile, "@") {
			return tx.Table("user").Where("email = ? and username = ?", mobile, username).Update("password", pwd).Error
		} else {
			return tx.Table("user").Where("mobile = ? and username = ?", mobile, username).Update("password", pwd).Error
		}
	})
	if res != nil {
		//db.Rollback()
		return errors.New("密码更新失败")
	}
	//db.Commit()
	return nil
}

func GetUserInfoByUid(db *gorm.DB, uid string) (models.User, error) {
	var u models.User
	res := db.Where("ID = ?", uid).First(&u)
	if res.Error != nil {
		loggers.Error(res.Error.Error())
		return models.User{}, errors.New("用户名不存在，请先注册.")
	}
	return u, nil
}

func UserLoginByUsername(db *gorm.DB, username, password string) (models.User, error) {
	var u models.User
	res := db.Where("username = ?", username).First(&u)
	if res.Error != nil {
		fmt.Println(res.Error)
		return models.User{}, errors.New("用户名不存在,请先注册")
	}
	if !common.VerifyPasswordNew(password, u.Password, variable.PwdKeyNew) {
		return models.User{}, errors.New("账号或密码错误")
	}
	return u, nil
}

func UserInsert(db *gorm.DB, mobile string, u *models.User) error {
	var us models.User
	res := db.Where("mobile=?", mobile).First(&us)
	if res.Error == nil || res.Row() != nil {
		return errors.New("该手机号已注册,请核查")
	}
	//db.Begin()
	err := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Table("user").Create(u).Error
	})
	if err != nil {
		//db.Rollback()
		loggers.Error(err.Error())
		return errors.New("用户注册失败,请稍后重试")
	}
	//db.Commit()
	return nil

}

func GetUserAll(db *gorm.DB) (data []models.User, err error) {
	res := db.Find(&data)
	if res.Error != nil {
		loggers.Error(res.Error)
		return nil, hmErrors.ErrMsg("获取数据错误")
	}
	return data, nil

}

func UpdateDC(db *gorm.DB, uid uint, days int) (err error) {
	//db.Begin()
	res := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		return tx.Table("user").Where("ID= ? ", uid).Update("days_count", days).Error
	})
	if res != nil {
		//db.Rollback()
		loggers.Error(res.Error())
		return errors.New("任务更新失败")
	}
	//db.Commit()
	return nil

}

func Transaction(db *gorm.DB, taskName, key string) error {
	//db.Begin()
	// 将任务信息存入数据库
	errTK := db.Transaction(func(tx *gorm.DB) error {
		return tx.Create(&models.TaskKey{
			TaskName:  taskName,
			TaskKey:   key,
			NotifyUrl: variable.NotifyUrl,
		}).Error
	})
	if errTK != nil {
		//db.Rollback()
		loggers.Error("Transaction failed: " + errTK.Error())
		return hmErrors.ErrOther("数据存入错误")
	}
	//db.Commit()
	return nil
}

func TransInsert(db *gorm.DB, boos interface{}) error {
	ok := false //类型断言一下
	if boos, ok = boos.(models.Boss); ok {
		boos = boos.(models.Boss)
	} else if boos, ok = boos.(models.Task); ok {
		boos = boos.(models.Task)
	} else {
		return hmErrors.ErrSystem("出现未知类型")
	}
	//db.Begin()
	err := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		// 在事务中执行一些 db 操作（从这里开始，您应该使用 'tx' 而不是 'db'）
		if err := tx.Create(&boos).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		//if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
		//	return err
		//}
		// 返回 nil 提交事务
		return nil
	})
	//result := db.Create(&boos)
	if err != nil {
		//db.Rollback()
		loggers.Info(fmt.Sprintf("插入数据失败:%v", err.Error()))
		return hmErrors.ErrSystem("数据插入事务失败")
	}
	//db.Commit()
	return nil
}

func TransInsertTaskKey(db *gorm.DB, data *models.Task) error {
	//ok := false //类型断言一下
	//if boos, ok = boos.(models.Boss); ok {
	//	boos = boos.(models.Boss)
	//} else if boos, ok = boos.(models.Task); ok {
	//	boos = boos.(models.Task)
	//} else {
	//	boos = boos.(models.Task)
	//return kernel.ErrSystem("出现未知类型")
	//}
	//db.Begin()
	err := db.Transaction(func(tx *gorm.DB) error {
		tx.Debug()
		// 在事务中执行一些 db 操作（从这里开始，您应该使用 'tx' 而不是 'db'）
		if err := tx.Create(&data).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		//if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
		//	return err
		//}
		// 返回 nil 提交事务
		return nil
	})
	//result := db.Create(&boos)
	if err != nil {
		//db.Rollback()
		loggers.Info(fmt.Sprintf("插入数据失败:%v", err.Error()))
		return hmErrors.ErrSystem("数据插入事务失败")
	}
	//db.Commit()
	return nil
}

func UpdateLastLogin(db *gorm.DB, userID uint) error {
	// 1. 检查记录是否存在
	var user models.User
	if err := db.Where("ID=?", userID).First(&user).Error; err != nil {
		return fmt.Errorf("用户不存在: %v", err)
	}

	// 2. 执行更新（跳过钩子、记录影响行数）
	result := db.Session(&gorm.Session{
		SkipHooks: true,
	}).Model(&models.User{}).Where("ID = ? AND deleted_at IS NULL", userID).
		Updates(map[string]interface{}{
			"last_login_at": time.Now(),
			"updated_at":    time.Now(),
		})

	if result.Error != nil {
		return result.Error
	}

	// 3. 明确检查影响行数
	if result.RowsAffected == 0 {
		return fmt.Errorf("更新失败：条件不匹配或记录已删除")
	}

	return nil
}

// GetUserWithRolesAndPermissions 获取用户及其角色和权限
func GetUserWithRolesAndPermissions(db *gorm.DB, userID uint) (*models.User, error) {
	var user models.User
	err := db.Preload("Roles.Permissions").First(&user, userID).Error
	return &user, err
}

// GetUserPermissions 获取用户所有权限(平铺)
func GetUserPermissions(db *gorm.DB, userID uint) ([]models.Permission, error) {
	var permissions []models.Permission

	err := db.Model(&models.User{BaseModel: models.BaseModel{ID: userID}}).
		Select("permissions.*").
		Joins("LEFT JOIN user_roles ON user_roles.ID = users.id").
		Joins("LEFT JOIN role_permissions ON role_permissions.role_id = user_roles.role_id").
		Joins("LEFT JOIN permissions ON permissions.id = role_permissions.permission_id").
		Distinct().
		Find(&permissions).Error

	return permissions, err
}

func AddUserAddress(db *gorm.DB, address *models.UserAddress) error {
	//db.Begin()
	err := db.Transaction(func(tx *gorm.DB) error {
		return tx.Create(address).Error
	})
	if err != nil {
		//db.Rollback()
		return fmt.Errorf("插入数据库失败:%v", err.Error())
	}
	//db.Commit()
	return nil
}

func GetUserAddress(db *gorm.DB, UserID uint) []models.UserAddress {
	var address []models.UserAddress
	_ = db.Where("user_id=?", UserID).Find(&address).Error
	return address
}

func GetUserInfo(db *gorm.DB, UserID uint) models.User {
	var user models.User
	_ = db.Where("ID=?", UserID).First(&user).Error
	return user
}

func Product_list(db *gorm.DB) []models.Product {
	var product []models.Product
	_ = db.Find(&product).Error
	return product
}

func GetProducts(db *gorm.DB, ids []int) []models.Product {
	var product []models.Product
	//result := db.Where("id IN ?", ids).Find(&users)
	_ = db.Where(map[string]interface{}{"id": ids}).Find(&product).Error
	return product
}

func CreateOrder(db *gorm.DB, order *models.Order) error {
	if err := db.Create(order).Error; err != nil {
		return fmt.Errorf("插入数据库失败:%v", err.Error())
	}
	return nil
}
